From 541950668be129ffa3dba3dadfd17c1bc033d516 Mon Sep 17 00:00:00 2001 From: robertl Date: Wed, 31 Jul 2002 22:54:20 +0000 Subject: [PATCH] Initial import. --- gpsman/COPYING | 339 +++++++++++++++++++++++ gpsman/Makefile | 15 ++ gpsman/README | 115 ++++++++ gpsman/README.contrib | 24 ++ gpsman/csv.c | 124 +++++++++ gpsman/defs.h | 106 ++++++++ gpsman/geo.c | 221 +++++++++++++++ gpsman/geocaching.loc | 1 + gpsman/gpsman | 53 ++++ gpsman/gpsman.c | 132 +++++++++ gpsman/gpsman2 | 75 ++++++ gpsman/gpsutil.c | 111 ++++++++ gpsman/gpx.c | 249 +++++++++++++++++ gpsman/magellan.h | 47 ++++ gpsman/magproto.c | 585 ++++++++++++++++++++++++++++++++++++++++ gpsman/main.c | 78 ++++++ gpsman/mapsend.c | 176 ++++++++++++ gpsman/mapsend.h | 37 +++ gpsman/mapsource.c | 136 ++++++++++ gpsman/pcx.c | 155 +++++++++++ gpsman/queue.c | 42 +++ gpsman/queue.h | 43 +++ gpsman/reference/gl.loc | 47 ++++ gpsman/reference/gu.wpt | 9 + gpsman/route.c | 47 ++++ gpsman/testo | 45 ++++ gpsman/tiger.c | 117 ++++++++ gpsman/util.c | 64 +++++ gpsman/vecs.c | 122 +++++++++ gpsman/waypt.c | 71 +++++ 30 files changed, 3386 insertions(+) create mode 100644 gpsman/COPYING create mode 100644 gpsman/Makefile create mode 100644 gpsman/README create mode 100644 gpsman/README.contrib create mode 100644 gpsman/csv.c create mode 100644 gpsman/defs.h create mode 100644 gpsman/geo.c create mode 100644 gpsman/geocaching.loc create mode 100644 gpsman/gpsman create mode 100644 gpsman/gpsman.c create mode 100644 gpsman/gpsman2 create mode 100644 gpsman/gpsutil.c create mode 100644 gpsman/gpx.c create mode 100644 gpsman/magellan.h create mode 100644 gpsman/magproto.c create mode 100644 gpsman/main.c create mode 100644 gpsman/mapsend.c create mode 100644 gpsman/mapsend.h create mode 100644 gpsman/mapsource.c create mode 100644 gpsman/pcx.c create mode 100644 gpsman/queue.c create mode 100644 gpsman/queue.h create mode 100644 gpsman/reference/gl.loc create mode 100644 gpsman/reference/gu.wpt create mode 100644 gpsman/route.c create mode 100755 gpsman/testo create mode 100644 gpsman/tiger.c create mode 100644 gpsman/util.c create mode 100644 gpsman/vecs.c create mode 100644 gpsman/waypt.c diff --git a/gpsman/COPYING b/gpsman/COPYING new file mode 100644 index 000000000..514d6c73f --- /dev/null +++ b/gpsman/COPYING @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place - Suite 330, Boston, MA 02111 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) 19yy + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/gpsman/Makefile b/gpsman/Makefile new file mode 100644 index 000000000..094ff43f5 --- /dev/null +++ b/gpsman/Makefile @@ -0,0 +1,15 @@ +CFLAGS=-g + +FMTS=magproto.o gpx.o geo.o gpsman.o mapsend.o mapsource.o \ + gpsutil.o tiger.o pcx.o csv.o + +OBJS=main.o queue.o route.o waypt.o util.o vecs.o $(FMTS) + +gpsbabel: $(OBJS) + $(CC) $(CFLAGS) $(OBJS) -o gpsbabel -lexpat -lm + +clean: + rm -f $(OBJS) gpsbabel + +mapsend.o: mapsend.h +magproto.o: magellan.h diff --git a/gpsman/README b/gpsman/README new file mode 100644 index 000000000..7856d7cc4 --- /dev/null +++ b/gpsman/README @@ -0,0 +1,115 @@ + +THE PROBLEM + + There are simply too many gratituosuly different file formats to + hold waypoint and route information in various programs used by + computers. GPX (http://www.topografix.com/gpx.asp) attempts to + define a standard in XML to contain all the data, but there are + too many programs that don't understand it yet and too much data + that are in an alternate format. + +THE SOLUTION + + I needed to convert waypoints between a couple of formats, so + I whipped up a converter and based it on an extensible foundation + so that it was easy to add new formats. Most file formats added + so far have taken under 200 lines of reasonable ISO C so they can + be stamped out pretty trivially. + +THE FORMATS + + GPX + + This is the most capable and expressive of all the file formats + supplied. It is described at http://www.topografix.com/gpx.asp + and is supported by EasyGPS, ExpertGPS, and man other programs + described at http://www.topografix.com/gpx_resources.asp + + GEO + + geocaching.com spits up geocaching.loc files that are XML-ish but + not quite GPX. Becuase it's so close to GPX, this format is very + well supported. + + MAGELLAN + + Waypoint upload and download works reliably. + + As of this writing, there is still a lot of "scribbling" in the + source for functionality that isn't hooked up to the rest of the + program. Communication errors are handled and verification of + data is turned on. + + GPSMAN + + GPS Manager can read and write formats that this converter doesn't + understand. The default formats (WGS84, DDD) work reliably. + + GPSUTIL + + GPSUtil has a simple file format of this program that runs on POSIX- + compliant OSes like UNIX and Linux. Reads and writes of this format + are reliable. (I've also contributed to this program.) It's + available at http://www.cs.uakron.edu/~hennings/gpsutil/. + + TIGER + + The U.S. Census Bureau proives online mapping facilities. This + format is described at: http://tiger.census.gov/instruct.html. + + CSV + + There are a billion variants of Comma Separated Value data. This + is the one that makes Delorme S&A Deluxe 9 happy. + + MAPSEND + + Magellan was smart enough to document their file format to make + creating software like this possible. It reads and writes only + waypoints (not routes) at this time. + + PCX + + Garmin documents only PCX5, an older format limited to the lame NMEA + six-character waypoint names that's treated as a second-class citizien + in current versions of MapSource. Use file->import to read these + files. Anyone with information on the *.mps file format that is + now preferred is encouraged to contact me with the details or better + yet, a module that implements it. I spent time trying to reverse- + engineer a couple of *.mps files then I remembered that I don't own + a Garmin and wasn't that inspired. + + +COMMON USAGE + + Invocation was meant to be flexible. Unfortunately, that can + sometimes lead to unwieldy command lines. + + mgps -? + + will always show you the supported file types. To use this + program, just tell it what you're reading, where to read it from, + what you're writing, and what to write it to. For example: + + mgps -i geo -f /tmp/geocaching.loc -o gpx -F /tmp/geocaching.gpx + + tells it to read the first file in geocaching.com format and create + a new file in GPX format. + + +ADVANCED USAGE + + Argument are processed in the order they appear on the command line. + Input is cumulative. The input file type remains unchanged until a + new -i argument is seen. Files are read in the order they appear. + So you could merge three input files into one output file with: + + mgps -i geo 1.loc 2.loc 3.loc -o geo -F big.loc + + You can merge files of different types: + + mgps -i geo 1.loc -i gpx 2.gpx -i pcx 3.pcx -o gpsutil -F big.gps + + You can write the same data in different output formats: + + mgps -i geo 1.loc -o gpx -F 1.gpx -o pcx 1.wpt diff --git a/gpsman/README.contrib b/gpsman/README.contrib new file mode 100644 index 000000000..e9028ea34 --- /dev/null +++ b/gpsman/README.contrib @@ -0,0 +1,24 @@ +If you're interested in contributing to this program, here are some +guidelines. Mail patches to robertlipe@usa.net for consideration and +integration. + +Standards are good. ISO C and POSIX are greal preferred. + +Reuse is OK, if not onerous. For example, using the expat libraries vastly + simplifies the XML parsers while increasing their robustness plus those + libraries are ubiquitous. So I consider it OK to require expat. + +If you contribute a new target, contribute a test case along with it. It's +not that hard and it helps us be sure that the next version of thie program +doesn't break your file format. + +Compilers complain for a reason. Code shouldn't emit warnings. + +The entire world doesn't run . I've tested this code on +five different OSes. If you find yourself wanting to insert compiler or +OS specific magic, please resist. + +Enjoy! + +Robert Lipe, +robertlipe@usa.net diff --git a/gpsman/csv.c b/gpsman/csv.c new file mode 100644 index 000000000..f97b20887 --- /dev/null +++ b/gpsman/csv.c @@ -0,0 +1,124 @@ +/* + Comma separated value files. + NAME,LONG, LAT. + + Copyright (C) 2002 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include "defs.h" +#include + +static FILE *file_in; +static FILE *file_out; + +static void +rd_init(const char *fname) +{ + file_in = fopen(fname, "r"); + if (file_in == NULL) { + fatal("GPSUTIL: Cannot open %s for reading\n", fname); + } +} + +static void +rd_deinit(void) +{ + fclose(file_in); +} + +static void +wr_init(const char *fname) +{ + file_out = fopen(fname, "w"); + if (file_out == NULL) { + fatal("GPSUTIL: Cannot open %s for writing\n", fname); + } +} + +static void +wr_deinit(void) +{ + fclose(file_out); +} + +static void +data_read(void) +{ + char name[9], desc[80]; + char *odesc = desc; + double lat,lon; + char latdir, londir; + long alt; + char alttype; + char icon[3] = {0}; + waypoint *wpt_tmp; + + while( fscanf(file_in, "%lf,%lf,%80[^\n]", + &lat, &lon, desc) > 0) { + wpt_tmp = calloc(sizeof(*wpt_tmp),1); + if (wpt_tmp == NULL) { + fatal("GPSMAN: cannot allocate memory\n"); + } + while (*odesc == ' ' || *odesc == '\t') { + odesc++; + } + wpt_tmp->shortname = strdup(odesc); + wpt_tmp->creation_time = time(NULL); + + wpt_tmp->position.longitude.degrees = lon; + wpt_tmp->position.latitude.degrees = lat; + + waypt_add(wpt_tmp); + } +} + +static void +gpsutil_disp(waypoint *wpt) +{ + double lon,lat; + signed int ilon, ilat; + const char *icon_token = "0"; + char tbuf[1024]; + char *tp = tbuf; + time_t tm = wpt->creation_time; + + lon = wpt->position.longitude.degrees; + lat = wpt->position.latitude.degrees; + + fprintf(file_out, "%08.5f, %08.5f, %s\n", + lat, + lon, + wpt->description); + +} + +static void +data_write(void) +{ + waypt_disp_all(gpsutil_disp); +} + + +ff_vecs_t csv_vecs = { + rd_init, + wr_init, + rd_deinit, + wr_deinit, + data_read, + data_write, +}; diff --git a/gpsman/defs.h b/gpsman/defs.h new file mode 100644 index 000000000..77b03cca0 --- /dev/null +++ b/gpsman/defs.h @@ -0,0 +1,106 @@ +/* + Copyright (C) 2002 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include +#include +#include +#include +#include +#include +#include "queue.h" + +/* + * Common definitions. There should be no protocol or file-specific + * data in this file. + */ + +/* + * A coordinate in space. + */ +typedef struct { + double degrees; +} coord; + + +/* + * An altitude is essentially a coordinate along only the Z axis. + */ + +typedef struct { + double altitude_meters; +} altitude; + + +/* + * A triplet of the coordinates along the three axes describes + * a position. + */ +typedef struct { + coord latitude; + coord longitude; + altitude altitude; +} position; + + +/* + * This is a waypoint, as stored in the GPSR. It tries to not + * cater to any specific model or protocol. Anything that needs to + * be truncated, edited, or otherwise trimmed should be done on the + * way to the target. + */ +typedef struct { + queue Q; + position position; + time_t time_created; + char *shortname; + char *description; + char *url; + char *url_link_text; + const char *icon_descr; + time_t creation_time; +} waypoint; + +typedef void (*ff_init) (char const *); +typedef void (*ff_deinit) (void); +typedef void (*ff_read) (void); +typedef void (*ff_write) (void); + +typedef void (*waypt_cb) (waypoint *); +void waypt_add (waypoint *); +void route_add (waypoint *); +void waypt_disp_all(waypt_cb); +unsigned int waypt_count(void); +void fprintdms(FILE *, coord *, int); + +typedef struct ff_vecs { + ff_init rd_init; + ff_init wr_init; + ff_deinit rd_deinit; + ff_deinit wr_deinit; + ff_read read; + ff_write write; +} ff_vecs_t; + +void waypt_init(void); +void route_init(void); +void waypt_disp(waypoint *); +void fatal(const char *, ...); +ff_vecs_t *find_vec(char *); + +void printposn(coord *c, int is_lat); diff --git a/gpsman/geo.c b/gpsman/geo.c new file mode 100644 index 000000000..5693aa45b --- /dev/null +++ b/gpsman/geo.c @@ -0,0 +1,221 @@ +/* + Copyright (C) 2002 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include +#include "defs.h" + +static int in_wpt; +static int in_name; +static int in_link; + +static XML_Parser psr; +static waypoint *wpt_tmp; + +FILE *fd; +FILE *ofd; + +static void +tag_coord(const char **attrv) +{ + const char **avp = &attrv[0]; + + + while (*avp) { + if (strcmp(avp[0], "lat") == 0) { + sscanf(avp[1], "%lf", + &wpt_tmp->position.latitude.degrees); + } + else if (strcmp(avp[0], "lon") == 0) { + sscanf(avp[1], "%lf", + &wpt_tmp->position.longitude.degrees); + } + avp+=2; + } +} + +static void +tag_name(const char **attrv) +{ + const char **avp = &attrv[0]; + while (*avp) { + if (strcmp(avp[0], "id") == 0) { + wpt_tmp->shortname = strdup(avp[1]); + } + avp+=2; + } +} + +static void +tag_link(const char **attrv) +{ + const char **avp = &attrv[0]; + while (*avp) { + if (strcmp(avp[0], "text") == 0) { + wpt_tmp->url_link_text = strdup(avp[1]); + } + avp+=2; + } +} + +static void +geo_start(void *data, const char *el, const char **attr) +{ + + if (in_wpt) { + if (strcmp(el, "ele") == 0) { + wpt_tmp->position.altitude.altitude_meters = atoi(attr[1]); + } + else if (strcmp(el, "name") == 0) { + tag_name(attr); + } + else if (strcmp(el, "coord") == 0) { + tag_coord(attr); + } + } + + if (strcmp(el, "waypoint") == 0) { + wpt_tmp = calloc(sizeof(*wpt_tmp), 1); + in_wpt++; + } else if (strcmp(el, "name") == 0) { + in_name++; + } else if (strcmp(el, "link") == 0) { + tag_link(attr); + in_link++; + } +} + +static void +geo_end(void *data, const char *el) +{ + if (strcmp(el, "waypoint") == 0) { + waypt_add(wpt_tmp); + in_wpt--; + } + else if (strcmp(el, "name") == 0) { + in_name--; + } + else if (strcmp(el, "link") == 0) { + in_link--; + } +} + +static void +geo_cdata(void *dta, const XML_Char *s, int len) +{ + char *foo = malloc(len+1); + foo[len] = 0; + strncpy(foo, s, len); + if (in_name) { + wpt_tmp->description = foo; + } + if (in_link) { + wpt_tmp->url = foo; + } +} + + +void +geo_rd_init(const char *fname) +{ + fd = fopen(fname, "r"); + if (fd == NULL) { + abort(); + } + + psr = XML_ParserCreate(NULL); + if (!psr) { + abort(); + } + + XML_SetElementHandler(psr, geo_start, geo_end); + XML_SetCharacterDataHandler(psr, geo_cdata); +} + +void +geo_rd_deinit(void) +{ + fclose(fd); +} + +void +geo_wr_init(const char *fname) +{ + ofd = fopen(fname, "w"); + if (ofd == NULL) { + abort(); + } +} + +void +geo_wr_deinit(void) +{ + fclose(ofd); +} + +void +geo_read(void) +{ + int len; + char buf[1024]; + + while ((len = fread(buf, 1, sizeof(buf), fd))) { + if (!XML_Parse(psr, buf, len, feof(fd))) { + fprintf(stderr, "Parse error at %d: %s\n", + XML_GetCurrentLineNumber(psr), + XML_ErrorString(XML_GetErrorCode(psr))); + exit(1); + } + } + +} + +static void +geo_waypt_pr(waypoint *waypointp) +{ + fprintf(ofd, "\n"); + fprintf(ofd, "", waypointp->shortname); + fprintf(ofd, "", waypointp->description); + fprintf(ofd, "\n"); + + fprintf(ofd, "", + waypointp->position.latitude.degrees, + waypointp->position.longitude.degrees); + fprintf(ofd, "\n"); + + fprintf(ofd, "%s\n", + waypointp->url); + fprintf(ofd, "\n"); +} + +void +geo_write(void) +{ + fprintf(ofd, "\n"); + waypt_disp_all(geo_waypt_pr); + fprintf(ofd, "\n"); +} + +ff_vecs_t geo_vecs = { + geo_rd_init, + geo_wr_init, + geo_rd_deinit, + geo_wr_deinit, + geo_read, + geo_write, +}; diff --git a/gpsman/geocaching.loc b/gpsman/geocaching.loc new file mode 100644 index 000000000..4073f2c98 --- /dev/null +++ b/gpsman/geocaching.loc @@ -0,0 +1 @@ +geocachehttp://www.geocaching.com/seek/cache_details.asp?ID=3771geocachehttp://www.geocaching.com/seek/cache_details.asp?ID=6711geocachehttp://www.geocaching.com/seek/cache_details.asp?ID=7211geocachehttp://www.geocaching.com/seek/cache_details.asp?ID=9641geocachehttp://www.geocaching.com/seek/cache_details.asp?ID=10019geocachehttp://www.geocaching.com/seek/cache_details.asp?ID=11121geocachehttp://www.geocaching.com/seek/cache_details.asp?ID=12447geocachehttp://www.geocaching.com/seek/cache_details.asp?ID=12666geocachehttp://www.geocaching.com/seek/cache_details.asp?ID=12669 \ No newline at end of file diff --git a/gpsman/gpsman b/gpsman/gpsman new file mode 100644 index 000000000..771a261f5 --- /dev/null +++ b/gpsman/gpsman @@ -0,0 +1,53 @@ +% Written by GPSManager 05-Apr-2002 21:52:36 (EST) +% Edit at your own risk! + +!Format: DMS 1 WGS 84 +!Creation: no + +!W: +GC894 N41 20 07.9 W85 24 31.9 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC1F78 N40 43 04.1 W85 06 25.1 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +003 N41 07 21.3 W85 09 23.5 symbol=boat_ramp alt=220.506469727 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC93 N41 43 09.4 W85 58 59.9 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC2193 N40 25 29.0 W86 54 52.0 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +004 N41 07 22.6 W85 09 24.3 symbol=flag alt=250.787719727 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GCA80 N40 29 14.3 W86 51 50.5 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC28CB N40 50 32.8 W85 25 20.8 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC2665 N40 45 56.4 W85 35 58.3 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +005 N41 02 51.4 W85 16 41.6 symbol=flag alt=263.044433594 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GCB78 N40 26 17.9 W86 54 02.2 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC2ADC N40 26 16.4 W86 48 21.6 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +ABACUS N41 04 20.6 W85 13 50.8 symbol=building alt=243.577880859 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GCD85 N41 05 03.3 W85 08 11.1 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GCB8 N40 26 09.5 W87 09 49.1 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC2BE8 N40 52 45.9 W85 32 26.1 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +CASH1 N41 04 41.8 W85 08 19.3 symbol=flag alt=245.740844727 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +H0ME N41 02 51.7 W85 16 42.1 symbol=house alt=272.176879883 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC2C81 N41 12 24.2 W85 02 23.5 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +CENCEN N41 41 39.0 W86 14 53.3 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +TOSB2 N41 44 00.4 W84 59 46.4 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC2C90 N40 50 08.2 W85 27 14.9 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +CWORK N41 07 23.0 W85 09 24.7 symbol=flag alt=254.633056641 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +TOSB3 N41 43 21.9 W86 15 20.3 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC2C91 N41 05 01.4 W85 08 18.7 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +FRSB1 N41 40 34.1 W86 15 01.1 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +UNITA N41 02 52.2 W85 16 41.6 symbol=flag alt=256.795898438 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC2F53 N41 43 57.0 W86 04 48.3 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +FRSB2 N41 38 10.3 W86 15 04.4 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC333A N41 01 42.7 W85 11 49.3 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +FRSB4 N41 37 27.7 W86 15 08.7 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +FRSB5 N41 38 53.4 W85 56 55.0 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC34D4 N41 58 16.8 W86 11 05.3 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +FRSB6 N41 34 46.3 W85 50 01.8 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC42A1 N41 05 02.1 W85 03 14.2 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC37C4 N41 38 15.5 W85 54 19.6 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +FRSB7 N41 07 42.2 W85 11 47.8 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC4378 N40 53 27.2 W85 28 13.4 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC11EF N40 01 45.3 W86 53 17.4 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC44E5 N41 01 03.7 W85 15 07.0 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC12FF N41 33 23.9 W86 21 26.9 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC47A5 N40 25 15.3 W86 54 17.6 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC17E0 N41 52 01.5 W86 36 12.5 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC488D N41 33 43.7 W85 50 18.3 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC1A9C N41 06 36.2 W85 09 20.8 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA + diff --git a/gpsman/gpsman.c b/gpsman/gpsman.c new file mode 100644 index 000000000..e115e7d82 --- /dev/null +++ b/gpsman/gpsman.c @@ -0,0 +1,132 @@ +/* + Copyright (C) 2002 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include "defs.h" + +static FILE *in_file; +static FILE *out_file; + +static void +gpsman_rd_init(const char *fname) +{ + in_file = fopen(fname, "r"); + if (in_file == NULL) { + fatal("GPSMAN: Cannot open %s for reading\n", fname); + } + +} +static void +gpsman_rd_deinit(void) +{ + fclose(in_file); +} + +static void +gpsman_wr_init(const char *fname) +{ + out_file = fopen(fname, "w"); + if (out_file == NULL) { + fatal("GPSMAN: Cannot open %s for writing\n", fname); + } + + fprintf(out_file, "!Format: DDD 1 WGS 84\n"); +} + +static void +gpsman_wr_deinit(void) +{ + fclose(out_file); +} + +static void +gpsman_disp(waypoint *waypointp) +{ + fprintf(out_file, "%-8.8s\t%s\t", + waypointp->shortname, waypointp->description); + fprintdms(out_file, &waypointp->position.latitude, 1); + fprintdms(out_file, &waypointp->position.longitude, 0); + fprintf(out_file,"\n"); +} + +static void +gpsman_parse_cmd(const char *cmd) +{ + return; +} + +static void +gpsman_read(void) +{ + char latdir, londir; + double latf, lonf; + int lonm, latm; + double lat, lon; + char sname[20]; + char descr[100]; + char ibuf[100]; + waypoint *wpt_tmp; + + while( fgets(ibuf, sizeof(ibuf), in_file)) { + if (ibuf[0] == '%' || ibuf[0] == '\n' ) { + continue; + } + if (ibuf[0] == '!') { + gpsman_parse_cmd(&ibuf[1]); + continue; + } + + sscanf(ibuf, "%[^\t] %[^\t] %c%d %lf %c%d %lf", + sname, descr, &latdir, &latm, &latf, &londir, &lonm, &lonf); + + wpt_tmp = calloc(sizeof(*wpt_tmp),1); + + if (wpt_tmp == NULL) { + fatal("GPSMAN: Cannot allocate enough memory\n"); + } + + lat = latm + latf; + lon = lonm + lonf; + + if (latdir == 'S') lat = -lat; + if (londir == 'W') lon = -lon; + + wpt_tmp->position.longitude.degrees = lon; + wpt_tmp->position.latitude.degrees = lat; + wpt_tmp->shortname = strdup(sname); + wpt_tmp->description = strdup(descr); + + waypt_add(wpt_tmp); + } +} + +static void +gpsman_write(void) +{ + fprintf(out_file, "!W:\n"); + waypt_disp_all(gpsman_disp); +} + +ff_vecs_t gpsman_vecs = { + gpsman_rd_init, + gpsman_wr_init, + gpsman_rd_deinit, + gpsman_wr_deinit, + gpsman_read, + gpsman_write, +}; diff --git a/gpsman/gpsman2 b/gpsman/gpsman2 new file mode 100644 index 000000000..4cf6db838 --- /dev/null +++ b/gpsman/gpsman2 @@ -0,0 +1,75 @@ +% Written by GPSManager 24-May-2002 13:51:04 (CST) +% Edit at your own risk! + +!Format: DMM 1 WGS 84 +!Creation: no + +!W: +!Position: DMS +GC37C4 N41 38 15.5 W85 54 19.6 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +H0ME N41 02 51.7 W85 16 42.1 symbol=house alt=272.176879883 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC894 N41 20 07.9 W85 24 31.9 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +FRSB7 N41 07 42.2 W85 11 47.8 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC2C81 N41 12 24.2 W85 02 23.5 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC1F78 N40 43 04.1 W85 06 25.1 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC4378 N40 53 27.2 W85 28 13.4 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +TOSB2 N41 44 00.4 W84 59 46.4 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +CENCEN N41 41 39.0 W86 14 53.3 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +003 N41 07 21.3 W85 09 23.5 symbol=boat_ramp alt=220.506469727 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC11EF N40 01 45.3 W86 53 17.4 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC2C90 N40 50 08.2 W85 27 14.9 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC93 N41 43 09.4 W85 58 59.9 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC12FF N41 33 23.9 W86 21 26.9 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC44E5 N41 01 03.7 W85 15 07.0 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +CWORK N41 07 23.0 W85 09 24.7 symbol=flag alt=254.633056641 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC2193 N40 25 29.0 W86 54 52.0 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC47A5 N40 25 15.3 W86 54 17.6 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +TOSB3 N41 43 21.9 W86 15 20.3 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +004 N41 07 22.6 W85 09 24.3 symbol=flag alt=250.787719727 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC17E0 N41 52 01.5 W86 36 12.5 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC2C91 N41 05 01.4 W85 08 18.7 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GCA80 N40 29 14.3 W86 51 50.5 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC488D N41 33 43.7 W85 50 18.3 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +FRSB1 N41 40 34.1 W86 15 01.1 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC28CB N40 50 32.8 W85 25 20.8 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC1A9C N41 06 36.2 W85 09 20.8 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +UNITA N41 02 52.2 W85 16 41.6 symbol=flag alt=256.795898438 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC2665 N40 45 56.4 W85 35 58.3 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC2F53 N41 43 57.0 W86 04 48.3 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +005 N41 02 51.4 W85 16 41.6 symbol=flag alt=263.044433594 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GCB78 N40 26 17.9 W86 54 02.2 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +FRSB2 N41 38 10.3 W86 15 04.4 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC2ADC N40 26 16.4 W86 48 21.6 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +FRSB4 N41 37 27.7 W86 15 08.7 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC333A N41 01 42.7 W85 11 49.3 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +ABACUS N41 04 20.6 W85 13 50.8 symbol=building alt=243.577880859 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +FRSB5 N41 38 53.4 W85 56 55.0 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GCD85 N41 05 03.3 W85 08 11.1 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC34D4 N41 58 16.8 W86 11 05.3 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GCB8 N40 26 09.5 W87 09 49.1 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +FRSB6 N41 34 46.3 W85 50 01.8 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC2BE8 N40 52 45.9 W85 32 26.1 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC42A1 N41 05 02.1 W85 03 14.2 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +CASH1 N41 04 41.8 W85 08 19.3 symbol=flag alt=245.740844727 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA + +!Position: DMM +!R: 34 +!Position: DMS +003 N41 07 21.3 W85 09 23.5 symbol=boat_ramp alt=220.506469727 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +004 N41 07 22.6 W85 09 24.3 symbol=flag alt=250.787719727 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +005 N41 02 51.4 W85 16 41.6 symbol=flag alt=263.044433594 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +ABACUS N41 04 20.6 W85 13 50.8 symbol=building alt=243.577880859 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +CASH1 N41 04 41.8 W85 08 19.3 symbol=flag alt=245.740844727 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +CENCEN N41 41 39.0 W86 14 53.3 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +CWORK N41 07 23.0 W85 09 24.7 symbol=flag alt=254.633056641 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +FRSB1 N41 40 34.1 W86 15 01.1 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC11EF N40 01 45.3 W86 53 17.4 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GCD85 N41 05 03.3 W85 08 11.1 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA + +!R: 23 Route 23 +!NB: blah blah blah + +GC11EF N40 01 45.3 W86 53 17.4 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC12FF N41 33 23.9 W86 21 26.9 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA +GC1A9C N41 06 36.2 W85 09 20.8 alt=-0.114379882812 GD108:class=|c! GD108:colour=~|Z GD108:attrs=` GD108:depth=QY|c%|_i GD108:state=|cAA GD108:country=|cAA + diff --git a/gpsman/gpsutil.c b/gpsman/gpsutil.c new file mode 100644 index 000000000..8e1dcf084 --- /dev/null +++ b/gpsman/gpsutil.c @@ -0,0 +1,111 @@ +/* + * written by robertlipe@usa.net + */ + +#include "defs.h" +#include "magellan.h" + +static FILE *file_in; +static FILE *file_out; + +static void +rd_init(const char *fname) +{ + file_in = fopen(fname, "r"); + if (file_in == NULL) { + fatal("GPSUTIL: Cannot open %s for reading\n", fname); + } +} + +static void +rd_deinit(void) +{ + fclose(file_in); +} + +static void +wr_init(const char *fname) +{ + file_out = fopen(fname, "w"); + if (file_out == NULL) { + fatal("GPSUTIL: Cannot open %s for writing\n", fname); + } +} + +static void +wr_deinit(void) +{ + fclose(file_out); +} + +static void +data_read(void) +{ + char name[9], desc[30]; + double lat,lon; + char latdir, londir; + long alt; + char alttype; + char icon[3] = {0}; + waypoint *wpt_tmp; + + while( fscanf(file_in, "%s %le%c %le%c %ld%c %30[^,] %c", + name, &lat, &latdir, &lon, &londir, + &alt, &alttype, desc, icon) > 0) { + wpt_tmp = calloc(sizeof(*wpt_tmp),1); + if (wpt_tmp == NULL) { + fatal("GPSMAN: cannot allocate memory\n"); + } + wpt_tmp->position.altitude.altitude_meters = alt; + wpt_tmp->shortname = strdup(name); + wpt_tmp->description = strdup(desc); + wpt_tmp->creation_time = time(NULL); + + if (latdir == 'S') lat = -lat; + if (londir == 'W') lon = -lon; + wpt_tmp->position.longitude.degrees = lon/100.0; + wpt_tmp->position.latitude.degrees = lat/100.0; + wpt_tmp->icon_descr = strdup(icon); + + waypt_add(wpt_tmp); + } +} + +static void +gpsutil_disp(waypoint *wpt) +{ + double lon,lat; + const char *icon_token; + + icon_token = mag_find_token_from_descr(wpt->icon_descr); + + lon = wpt->position.longitude.degrees * 100.0; + lat = wpt->position.latitude.degrees * 100.0; + + fprintf(file_out, "%-8s %08.3f%c %09.3f%c %07.0f%c %-30.30s %s\n", + wpt->shortname, + fabs(lat), + lat < 0.0 ? 'S' : 'N', + fabs(lon), + lon < 0.0 ? 'W' : 'E', + wpt->position.altitude.altitude_meters, + 'm', + wpt->description, + icon_token); +} + +static void +data_write(void) +{ + waypt_disp_all(gpsutil_disp); +} + + +ff_vecs_t gpsutil_vecs = { + rd_init, + wr_init, + rd_deinit, + wr_deinit, + data_read, + data_write, +}; diff --git a/gpsman/gpx.c b/gpsman/gpx.c new file mode 100644 index 000000000..743fe869c --- /dev/null +++ b/gpsman/gpx.c @@ -0,0 +1,249 @@ +/* + Access GPX data files. + + Copyright (C) 2002 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include +#include "defs.h" + +static int in_wpt; +static int in_rte; +static int in_ele; +static int in_name; +static int in_time; +static int in_desc; + +static XML_Parser psr; + +static const char *gpx_version; +static const char *gpx_creator; + +static waypoint *wpt_tmp; +static FILE *fd; +static FILE *ofd; + +static void +tag_gpx(const char **attrv) +{ + const char **avp = &attrv[0]; + while (*avp) { + if (strcmp(avp[0], "version") == 0) { + gpx_version = avp[1]; + } + else if (strcmp(avp[0], "src") == 0) { + gpx_creator = avp[1]; + } + avp+=2; + } +} + +static void +tag_wpt(const char **attrv) +{ + const char **avp = &attrv[0]; + + wpt_tmp = calloc(sizeof(*wpt_tmp), 1); + if (wpt_tmp == NULL) { + fatal("Can not allocate memory\n"); + } + + while (*avp) { + if (strcmp(avp[0], "lat") == 0) { + sscanf(avp[1], "%lf", + &wpt_tmp->position.latitude.degrees); + } + else if (strcmp(avp[0], "lon") == 0) { + sscanf(avp[1], "%lf", + &wpt_tmp->position.longitude.degrees); + } + avp+=2; + } +} + +static void +gpx_start(void *data, const char *el, const char **attr) +{ + + if (strcmp(el, "ele") == 0) { + in_ele++; + } if (strcmp(el, "name") == 0) { + in_name ++; + } if (strcmp(el, "gpx") == 0) { + tag_gpx(attr); + } if (strcmp(el, "wpt") == 0) { + in_wpt++; + tag_wpt(attr); + } if (strcmp(el, "desc") == 0) { + in_desc++; + } if (strcmp(el, "rtept") == 0) { + in_rte++; + tag_wpt(attr); + } if (strcmp(el, "time") == 0) { + in_time++; + } +} + +static void +gpx_end(void *data, const char *el) +{ + if (strcmp(el, "wpt") == 0) { + waypt_add(wpt_tmp); + in_wpt--; + } + else if (strcmp(el, "rtept") == 0) { + route_add(wpt_tmp); + in_rte--; + } else if (strcmp(el, "name") == 0) { + in_name--; + } else if (strcmp(el, "desc") == 0) { + in_desc--; + } else if (strcmp(el, "ele") == 0) { + in_ele--; + } else if (strcmp(el, "time") == 0) { + in_time--; + } +} + +static void +gpx_cdata(void *dta, const XML_Char *s, int len) +{ + char *foo = malloc(len+1); + foo[len] = 0; + strncpy(foo, s, len); + if (in_name && in_wpt) { + wpt_tmp->shortname = foo; + } + if (in_desc) { + wpt_tmp->description = foo; + } + if (in_ele) { + sscanf(foo, "%lf", + &wpt_tmp->position.altitude.altitude_meters); + } + if (in_time && (in_wpt || in_rte)) { + struct tm tm; + sscanf(foo, "%d-%d-%dT%d:%d:%dZ\n", + &tm.tm_year, + &tm.tm_mon, + &tm.tm_mday, + &tm.tm_hour, + &tm.tm_min, + &tm.tm_sec); + tm.tm_mon -= 1; + tm.tm_year -= 1900; + tm.tm_isdst = 1; + wpt_tmp->creation_time = mktime(&tm); + } +} + +void +gpx_rd_init(const char *fname) +{ + fd = fopen(fname, "r"); + if (fd == NULL) { + fatal("GPX: Cannot open %s for reading\n", fname ); + } + psr = XML_ParserCreate(NULL); + if (!psr) { + fatal("GPX: Cannot create XML Parser\n"); + } + XML_SetElementHandler(psr, gpx_start, gpx_end); + XML_SetCharacterDataHandler(psr, gpx_cdata); +} + +static void +gpx_rd_deinit(void) +{ + fclose(fd); +} + +void +gpx_wr_init(const char *fname) +{ + ofd = fopen(fname, "w"); + if (ofd == NULL) { + fatal("GPX: Cannot open %s for writing\n", fname ); + } +} + +static void +gpx_wr_deinit(void) +{ + fclose(ofd); +} +void +gpx_read(void) +{ + int len; + int done = 0; + char buf[102400]; + + while (!done) { + len = fread(buf, 1, sizeof(buf), fd); + done = feof(fd); + if (!XML_Parse(psr, buf, len, done)) { + fatal("GPX: XML parse error at %d: %s\n", + XML_GetCurrentLineNumber(psr), + XML_ErrorString(XML_GetErrorCode(psr))); + } + } +} + +static void +gpx_waypt_pr(waypoint *waypointp) +{ + + fprintf(ofd, "\n", + waypointp->position.latitude.degrees, + waypointp->position.longitude.degrees); + fprintf(ofd, "%s\n", waypointp->shortname); + fprintf(ofd, ""); + fprintf(ofd, "", waypointp->description); + fprintf(ofd, "\n"); + if (waypointp->position.altitude.altitude_meters) { + fprintf(ofd, "\n%f\n\n", + waypointp->position.altitude.altitude_meters); + } + if (waypointp->url) { + fprintf(ofd, "%s\n", waypointp->url); + } + if (waypointp->url_link_text) { + fprintf(ofd, "%s\n", + waypointp->url_link_text); + } + fprintf(ofd, "\n"); +} + +void +gpx_write(void) +{ + fprintf(ofd, "\n"); + fprintf(ofd, "\n"); + waypt_disp_all(gpx_waypt_pr); + fprintf(ofd, "\n"); +} + +ff_vecs_t gpx_vecs = { + gpx_rd_init, + gpx_wr_init, + gpx_rd_deinit, + gpx_wr_deinit, + gpx_read, + gpx_write, +}; diff --git a/gpsman/magellan.h b/gpsman/magellan.h new file mode 100644 index 000000000..b1d384b72 --- /dev/null +++ b/gpsman/magellan.h @@ -0,0 +1,47 @@ +/* + Copyright (C) 2002 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +/* + * Table of "interesting" Magellan models. + * Selfishly, if I haven't heard of it, it's not in the table. + * This doesn't mean I actually have TRIED all models listed below. + * (Donations welcome. :-) + */ +typedef enum { + mm_unknown, + mm_gps315320, + mm_map410, + mm_map330, + mm_gps310, + mm_meridian +} meridian_model; + +typedef struct pid_to_model { + meridian_model model; + int pid; + const char *model_n; +} pid_to_model_t; + +typedef struct icon_mapping { + const char *token; + const char *icon; +} icon_mapping_t; + +const char * mag_find_descr_from_token(const char *token); +const char * mag_find_token_from_descr(const char *icon); diff --git a/gpsman/magproto.c b/gpsman/magproto.c new file mode 100644 index 000000000..e23cdbab6 --- /dev/null +++ b/gpsman/magproto.c @@ -0,0 +1,585 @@ +/* + Communicate Thales/Magellan serial protocol. + + Copyright (C) 2002 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include +#include + +#include "defs.h" +#include "magellan.h" + +#define debug 1 + +typedef enum { + mrs_handoff = 0, + mrs_handon +} mag_rxstate; + +static FILE *magfile; +static int magfd; +static mag_rxstate magrxstate; +static struct termios orig_tio; +static int last_rx_csum; +static int found_done; +static icon_mapping_t *icon_mapping; + +static waypoint * mag_wptparse(char *); + +static icon_mapping_t gps315_icon_table[] = { + { "a", "filled circle" }, + { "b", "box" }, + { "c", "red buoy" }, + { "d", "green buoy" }, + { "e", "buoy" }, + { "f", "rocks" }, + { "g", "red daymark" }, + { "h", "green daymark" }, + { "i", "bell" }, + { "j", "danger" }, + { "k", "diver down" }, + { "l", "fish" }, + { "m", "house" }, + { "n", "mark" }, + { "o", "car" }, + { "p", "tent" }, + { "q", "boat" }, + { "r", "food" }, + { "s", "fuel" }, + { "t", "tree" }, + { NULL, NULL } +}; + +static icon_mapping_t map330_icon_table[] = { + { "a", "crossed square" }, + { "b", "box" }, + { "c", "house" }, + { "d", "aerial" }, + { "e", "airport" }, + { "f", "amusement park" }, + { "g", "ATM" }, + { "h", "auto repair" }, + { "i", "boating" }, + { "j", "camping" }, + { "k", "exit ramp" }, + { "l", "first aid" }, + { "m", "nav aid" }, + { "n", "buoy" }, + { "o", "fuel" }, + { "p", "garden" }, + { "q", "golf" }, + { "r", "hotel" }, + { "s", "hunting/fishing" }, + { "t", "large city" }, + { "u", "lighthouse" }, + { "v", "major city" }, + { "w", "marina" }, + { "x", "medium city" }, + { "y", "museum" }, + { "z", "obstruction" }, + { "aa", "park" }, + { "ab", "resort" }, + { "ac", "restaraunt" }, + { "ad", "rock" }, + { "ae", "scuba" }, + { "af", "RV service" }, + { "ag", "shooting" }, + { "ah", "sight seeing" }, + { "ai", "small city" }, + { "aj", "sounding" }, + { "ak", "sports arena" }, + { "al", "tourist info" }, + { "am", "truck service" }, + { "an", "winery" }, + { "ao", "wreck" }, + { "ap", "zoo" }, + { NULL, NULL } +}; + +pid_to_model_t pid_to_model[] = +{ + { mm_gps315320, 24, "GPS 315/320" }, + { mm_map410, 25, "Map 410" }, + { mm_map330, 30, "Map 330" }, + { mm_gps310, 31, "GPS 310" }, + { mm_meridian, 33, "Meridian" }, + { 0, 0, NULL } +}; + + +/* + * Given a protocol message, compute the checksum as needed by + * the Magellan protocol. + */ +static unsigned int +mag_checksum(const char * const buf) +{ + int csum = 0; + const char *p; + + for(p = buf; *p; p++) { + csum ^= *p; + } + + return csum; +} +static unsigned int +mag_pchecksum(const char * const buf, int len) +{ + int csum = 0; + const char *p = buf; + for (; len ; len--) { + csum ^= *p++; + } + return csum; +} + +static void +mag_writemsg(const char * const buf) +{ + unsigned int osum = mag_checksum(buf); + + if (debug) { + fprintf(stderr,"WRITE: $%s*%02X\r\n",buf, osum); + } +#if 0 + retry: +#endif + fprintf(magfile, "$%s*%02X\r\n",buf, osum); +#if 0 + if (magrxstate == mrs_handon) { + mag_readmsg(); + if (last_rx_csum != osum) { +fprintf(stderr, "E"); + goto retry; + } + } +#endif +} +static void +mag_writeack(int osum) +{ + char obuf[100]; + snprintf(obuf, sizeof(obuf), "PMGNCSM,%02X", osum); + mag_writemsg(obuf); +} + +static void +mag_handon(void) +{ + magrxstate = mrs_handon; + mag_writemsg("PMGNCMD,HANDON"); +} + +static void +mag_handoff(void) +{ + magrxstate = mrs_handoff; + mag_writemsg("PMGNCMD,HANDOFF"); +} + +void +mag_verparse(char *ibuf) +{ + int prodid = mm_unknown; + char version[1024]; + pid_to_model_t *pp = pid_to_model; + sscanf(ibuf,"$PMGNVER,%d,%[^,]", &prodid, version); + + for (pp = pid_to_model; pp->model ; pp++) { + if (pp->pid == prodid) { + break; + } + } + switch (pp->model) { + case mm_gps315320: + case mm_map410: + icon_mapping = gps315_icon_table; + break; + case mm_map330: + case mm_meridian: + icon_mapping = map330_icon_table; + break; + default: + abort(); + } +} + +#define IS_TKN(x) (strncmp(ibuf,x, sizeof(x)-1) == 0) + +static void +mag_readmsg(void) +{ + char ibuf[100]; + int isz; + unsigned int isum; + char *isump; + fgets(ibuf, sizeof(ibuf), magfile); + isz = strlen(ibuf); + if (isz < 5) { +if (debug) +fprintf(stderr, "SHORT READ %d\n", isz); + return; + } + while (!isprint(ibuf[isz])) + isz--; + isump = &ibuf[isz-1]; + isum = strtoul(isump, NULL,16); + if (isum != mag_pchecksum(&ibuf[1], isz-3)) { +if (debug) + fprintf(stderr, "RXERR %02x/%02x: '%s'\n", isum, mag_pchecksum(&ibuf[1],isz-5), ibuf); + } +if (debug) +fprintf(stderr, "READ: %s\n", ibuf); + if (IS_TKN("$PMGNCSM,")) { + last_rx_csum = strtoul(&ibuf[9], NULL, 16); + return; + } + if (strncmp(ibuf, "$PMGNWPT,", 7) == 0) { + waypoint *wpt = mag_wptparse(ibuf); + waypt_add(wpt); + } + if (IS_TKN("$PMGNVER,")) { + mag_verparse(ibuf); +return; + } + if (IS_TKN("$PMGNCMD,END")) { + found_done = 1; +return; + } + mag_writeack(isum); +} + +static void +mag_rd_init(const char *portname) +{ + struct termios new_tio; + magfile = fopen(portname, "rw+b"); + + if (magfile == NULL) { + perror("Open failed"); + return; + } + + magfd = fileno(magfile); + tcgetattr(magfd, &orig_tio); + new_tio = orig_tio; + new_tio.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL| + IXON); + new_tio.c_oflag &= ~OPOST; + new_tio.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN); + new_tio.c_cflag &= ~(CSIZE|PARENB); + new_tio.c_cflag |= CS8; + + cfsetospeed(&new_tio, B4800); + cfsetispeed(&new_tio, B4800); + tcsetattr(magfd, TCSAFLUSH, &new_tio); + + mag_handon(); + mag_writemsg("PMGNCMD,VERSION"); + mag_writemsg("PMGNCMD,NMEAOFF"); + return; +} + +static void +mag_deinit(void) +{ + mag_handoff(); + tcsetattr(magfd, TCSANOW, &orig_tio); + fclose(magfile); +} + +/* + * Given an incoming track messages of the form: + * $PMGNTRK,3605.259,N,08644.389,W,00151,M,201444.61,A,,020302*66 + * create and return a populated waypoint. + */ +waypoint * +mag_trkparse(char *trkmsg) +{ + double latdeg, lngdeg; + int alt; + char altunits; + char lngdir, latdir; + int dmy; + int hms; + int fracsecs; + struct tm tm; + waypoint *waypt; + + waypt = calloc(sizeof *waypt, 1); + if (waypt == NULL) + return NULL; + + printf("%s\n", trkmsg); + memset(&tm, 0, sizeof(tm)); +#if 0 + sscanf(trkmsg,"$PMGNTRK,%lf,%c,%lf,%c,%d,%c,%d.%d,A,,%d", + &latdeg,&latdir, + &lngdeg,&lngsecs,&lngdir, + &alt,&altunits,&hms,&fracsecs,&dmy); +#else +latdeg = 123; +#endif + + tm.tm_sec = hms % 100; + hms = hms / 100; + tm.tm_min = hms % 100; + hms = hms / 100; + tm.tm_hour = hms % 100; + + tm.tm_mon = dmy % 100; + dmy = dmy / 100; + tm.tm_mday = dmy % 100; + dmy = dmy / 100; + tm.tm_year = 100 + dmy % 100; + + /* + * FIXME: mktime assumes the struct tm is in local time, which + * ours is not... + */ + waypt->time_created = mktime(&tm); + + waypt->position.latitude.degrees = latdeg / 100.0; + waypt->position.longitude.degrees = lngdeg / 100.0; + waypt->position.altitude.altitude_meters = alt; + + return waypt; + +} + +const char * +mag_find_descr_from_token(const char *token) +{ + icon_mapping_t *i = icon_mapping; + + if (icon_mapping == NULL) { + return "unknown"; + } + + for (i = icon_mapping; i->token; i++) { + if (strcmp(token, i->token) == 0) + return i->icon; + } + return icon_mapping[0].icon; +} + +const char * +mag_find_token_from_descr(const char *icon) +{ + icon_mapping_t *i = icon_mapping; + + if (i == NULL || icon == NULL) { + return "a"; + } + + for (i = icon_mapping; i->token; i++) { + if (strcmp(icon, i->icon) == 0) + return i->token; + } + return icon_mapping[0].token; +} + + +/* + * Given an incoming waypoint messages of the form: + * $PMGNWPL,3549.499,N,08650.827,W,0000257,M,HOME,HOME,c*4D + * create and return a populated waypoint. + */ +waypoint * +mag_wptparse(char *trkmsg) +{ + double latdeg, lngdeg; + char latdir; + char lngdir; + int alt; + char altunits; + char shortname[100]; + char descr[100]; + char icon_token[100]; + waypoint *waypt; + char *icons; + char *icone; + char *blah; + int i = 0; + + descr[0] = 0; + icon_token[0] = 0; + + waypt = calloc(sizeof *waypt, 1); + if (waypt == NULL) + fatal("Magproto: Cannot allocate memory\n"); + + sscanf(trkmsg,"$PMGNWPL,%lf,%c,%lf,%c,%d,%c,%[^,],%[^,]", + &latdeg,&latdir, + &lngdeg,&lngdir, + &alt,&altunits,shortname,descr); + icone = strrchr(trkmsg, '*'); + icons = strrchr(trkmsg, ',')+1; + + for (blah = icons ; blah < icone; blah++) + icon_token[i++] = *blah; + + if (latdir == 'S') latdeg = -latdeg; + waypt->position.latitude.degrees = latdeg / 100.0; + + if (lngdir == 'W') lngdeg = -lngdeg; + waypt->position.longitude.degrees = lngdeg / 100.0; + + waypt->position.altitude.altitude_meters = alt; + waypt->shortname = strdup(shortname); + waypt->description = strdup(descr); + waypt->icon_descr = mag_find_descr_from_token(icon_token); + + return waypt; +} + +#if BLERF + +int main(void) +{ +char trk1[] = "$PMGNTRK,3605.259,N,08644.389,W,00151,M,201444.61,A,,020302*66"; +char trk2[] = "$PMGNTRK,3605.315,N,08644.625,W,00153,M,211618.68,A,,020302*6D"; +char trk3[] = "$PMGNTRK,3605.320,N,08644.619,W,00164,M,212121.87,A,,020302*6F"; +char wpt1[] = "$PMGNWPL,3604.831,N,08659.737,W,0000000,M,PowerPln,Power Plant by White Dog Pack,a*50"; +char wpt2[] = "$PMGNWPL,3614.645,N,08641.885,W,0000000,M,CmbrlndR,Cumberland River Cache by GISG,a*7B"; +char wpt3[] = "$PMGNWPL,3608.210,N,08648.389,W,0000000,M,Puff!,Puff! by White Dog Pack,a*61"; +waypt_init(); +route_init(); + +#if 1 +mag_trkparse(trk1); +mag_trkparse(trk2); +mag_trkparse(trk3); + +exit(0); +#endif + +#if 1 +mag_wptparse(wpt1); +mag_wptparse(wpt2); +mag_wptparse(wpt3); +exit(0); +#endif + mag_init(); + +#if 1 + mag_writemsg("PMGNCMD,WAYPOINT"); +while (!found_done) { + mag_readmsg(); +} +exit(0); +#endif +#if 0 + mag_writemsg("PMGNCMD,TRACK,2"); +while (!found_done) { + mag_readmsg(); +} +#endif +#if 1 + mag_writemsg("PMGNCMD,ROUTE"); +while (!found_done) { + mag_readmsg(); +} +exit(0); +#endif +#if 0 + mag_writemsg("PMGNCMD,FIL,FIRST,?"); +sleep(2); + mag_readmsg(); +while (!found_done) { + mag_writemsg("PMGNCMD,FIL,NEXT"); + mag_readmsg(); +sleep(2); +} +#endif + mag_deinit(); + return 0; +} + +#if SOON +/* ROUTES */ +READ: $PMGNRTE,3,1,c,19,HOME,c,KidsAtPl,a*0F +READ: $PMGNRTE,3,2,c,19,TrainWrc,a,Leipers,a*6F +READ: $PMGNRTE,3,3,c,19,Nashvill,a,HOME,c*1A + +/* WAYPOINTS */ +READ: $PMGNWPL,3604.831,N,08659.737,W,0000000,M,PowerPln,Power Plant by White Do +READ: $PMGNWPL,3614.645,N,08641.885,W,0000000,M,CmbrlndR,Cumberland River Cache +READ: $PMGNWPL,3608.210,N,08648.389,W,0000000,M,Puff!,Puff! by White Dog Pack,a* +61 + +#endif +#endif + +void +mag_readwpt(void) +{ + mag_writemsg("PMGNCMD,WAYPOINT"); + while (!found_done) { + mag_readmsg(); + } +} + +static +void +mag_waypt_pr(waypoint *waypointp) +{ + double lon, lat; + double ilon, ilat; + char obuf[200]; + ilat = waypointp->position.latitude.degrees; + ilon = waypointp->position.longitude.degrees; + + lon =fabs(ilon * 100.0); + lat =fabs(ilat * 100.0); + + sprintf(obuf, "PMGNWPL,%4.3f,%c,%05.3f,%c,%.lf,M,%-.8s,%-.20s,%s", + lat, ilon < 0 ? 'N' : 'S', + lon, ilat < 0 ? 'E' : 'W', + waypointp->position.altitude.altitude_meters, + waypointp->shortname, + waypointp->description, + waypointp->icon_descr); + mag_writemsg(obuf); + mag_readmsg(); +} + + +void +mag_write(void) +{ +#if 1 + mag_readmsg(); + mag_readmsg(); + mag_readmsg(); + mag_readmsg(); +#endif + waypt_disp_all(mag_waypt_pr); + +} + +ff_vecs_t mag_vecs = { + mag_rd_init, + mag_rd_init, + mag_deinit, + mag_deinit, + mag_readwpt, + mag_write, +}; diff --git a/gpsman/main.c b/gpsman/main.c new file mode 100644 index 000000000..c10b2c8b9 --- /dev/null +++ b/gpsman/main.c @@ -0,0 +1,78 @@ +/* + Copyright (C) 2002 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + + +#include "defs.h" +#include + +void +usage(const char *pname) +{ + printf("Usage: %s -i -f -o -F \n", pname); + printf("Supported file types:\n"); + disp_vecs(); +} + +int +main(int argc, char *argv[]) +{ + int c; + ff_vecs_t *ivecs = NULL; + ff_vecs_t *ovecs = NULL; + char *fname = NULL; + char *ofname = NULL; + + waypt_init(); + route_init(); + + while (( c = getopt(argc, argv, "?hi:o:f:F:")) != EOF) { + switch (c) { + case 'i': + ivecs = find_vec(optarg); + break; + case 'o': + ovecs = find_vec(optarg); + break; + case 'f': + fname = optarg; + if (ivecs == NULL) { + fatal ("No valid input type specified"); + } + ivecs->rd_init(fname); + ivecs->read(); + break; + case 'F': + ofname = optarg; + if (ovecs) { + ovecs->wr_init(ofname); + ovecs->write(); + } + break; + case 'h': + case '?': + usage(argv[0]); + exit(0); + } + } + + if (ovecs == NULL) + waypt_disp_all(waypt_disp); + + exit(0); +} diff --git a/gpsman/mapsend.c b/gpsman/mapsend.c new file mode 100644 index 000000000..6a913da2d --- /dev/null +++ b/gpsman/mapsend.c @@ -0,0 +1,176 @@ +/* + Access Magellan Mapsend files. + + Copyright (C) 2002 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + */ + +#include +#include + +#include "defs.h" +#include "mapsend.h" + +static FILE *mapsend_file_in; +static FILE *mapsend_file_out; + +static void +mapsend_rd_init(const char *fname) +{ + mapsend_file_in = fopen(fname, "r"); + if (mapsend_file_in == NULL) { + fprintf(stderr, "Cannot open '%s' for reading\n", fname); + exit(1); + } +} + +static void +mapsend_rd_deinit(void) +{ + fclose(mapsend_file_in); +} + +static void +mapsend_wr_init(const char *fname) +{ + mapsend_file_out = fopen(fname, "w"); + if (mapsend_file_out == NULL) { + fprintf(stderr, "Cannot open '%s' for writing\n", fname); + exit(1); + } +} + +static void +mapsend_wr_deinit(void) +{ + fclose(mapsend_file_out); +} + +static void +mapsend_read(void) +{ + mapsend_hdr hdr; + char tbuf[256]; + char name[257]; + char comment[257]; + char *p; + int wpt_count; + unsigned char scount; + int wpt_number; + char wpt_icon; + char wpt_status; + double wpt_alt; + double wpt_long; + double wpt_lat; + waypoint *wpt_tmp; + + /* + * Becuase of the silly struct packing and the goofy variable-length + * strings, each member has to be read in one at a time. Grrr. + */ + + fread(&hdr, sizeof(hdr), 1, mapsend_file_in); + + fread(&wpt_count, sizeof(wpt_count), 1, mapsend_file_in); + + while (wpt_count--) { + wpt_tmp = calloc(sizeof(*wpt_tmp), 1); + + fread(&scount, sizeof(scount), 1, mapsend_file_in); + fread(&tbuf, scount, 1, mapsend_file_in); + p = strncpy(name, tbuf, scount); + p[scount] = '\0'; + + fread(&scount, sizeof(scount), 1, mapsend_file_in); + fread(&tbuf, scount, 1, mapsend_file_in); + p = strncpy(comment, tbuf, scount); + p[scount] = '\0'; + + fread(&wpt_number, sizeof(wpt_number), 1, mapsend_file_in); + fread(&wpt_icon, sizeof(wpt_icon), 1, mapsend_file_in); + fread(&wpt_status, sizeof(wpt_status), 1, mapsend_file_in); + fread(&wpt_alt, sizeof(wpt_alt), 1, mapsend_file_in); + fread(&wpt_long, sizeof(wpt_long), 1, mapsend_file_in); + fread(&wpt_lat, sizeof(wpt_lat), 1, mapsend_file_in); + + wpt_tmp->shortname = strdup(name); + wpt_tmp->description = strdup(comment); + wpt_tmp->position.altitude.altitude_meters = wpt_alt; + wpt_tmp->position.latitude.degrees = -wpt_lat; + wpt_tmp->position.longitude.degrees = wpt_long; + + waypt_add(wpt_tmp); + } +} + +static void +mapsend_waypt_pr(waypoint *waypointp) +{ + int n; + double falt; + double flong; + double flat; +static int cnt = 0; + + n = strlen(waypointp->shortname); + fwrite(&n, 1, 1, mapsend_file_out); + fwrite(waypointp->shortname, n, 1, mapsend_file_out); + + n = strlen(waypointp->description); + fwrite(&n, 1, 1, mapsend_file_out); + fwrite(waypointp->description, n, 1, mapsend_file_out); + + /* #, icon, status */ +n = ++cnt; + fwrite(&n, 4, 1, mapsend_file_out); +n = 0; + fwrite(&n, 1, 1, mapsend_file_out); +n = 1; + fwrite(&n, 1, 1, mapsend_file_out); + + falt = waypointp->position.altitude.altitude_meters; + fwrite(&falt, sizeof(double), 1, mapsend_file_out); + + flong = waypointp->position.longitude.degrees; + fwrite(&flong, sizeof(double), 1, mapsend_file_out); + flat = -waypointp->position.latitude.degrees; + fwrite(&flat, sizeof(double), 1, mapsend_file_out); +} + +void +mapsend_write(void) +{ + mapsend_hdr hdr = {13, "4D533330 MS", "30", 1}; + int wpt_count = waypt_count(); +int n = 0; + + fwrite(&hdr, sizeof(hdr), 1, mapsend_file_out); + fwrite(&wpt_count, sizeof(wpt_count), 1, mapsend_file_out); + + waypt_disp_all(mapsend_waypt_pr); + + fwrite(&n, 4, 1, mapsend_file_out); +/* TODO: Impelment routes here */ +} + +ff_vecs_t mapsend_vecs = { + mapsend_rd_init, + mapsend_wr_init, + mapsend_rd_deinit, + mapsend_wr_deinit, + mapsend_read, + mapsend_write, +}; diff --git a/gpsman/mapsend.h b/gpsman/mapsend.h new file mode 100644 index 000000000..2e617fcba --- /dev/null +++ b/gpsman/mapsend.h @@ -0,0 +1,37 @@ +/* + Access to MapSend files. + + Copyright (C) 2002 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + * + * Information from: + * Mapsend File Format Description Revision 1.1, March 6, 2002 from Thales. + * + * Note this file format was clearly NOT designed for cross-architecture + * portability. In fact, becuase of the pascal nature of the 'string' + * data type described in that document, it's impractical to describe + * a 'struct waypoint' in C. + * + */ + +typedef struct { + char ms_length; + char ms_signature[11]; + char ms_version[2]; + char ms_type; + char _ms_type[3]; +} mapsend_hdr; diff --git a/gpsman/mapsource.c b/gpsman/mapsource.c new file mode 100644 index 000000000..446da1426 --- /dev/null +++ b/gpsman/mapsource.c @@ -0,0 +1,136 @@ +/* + Acess to Garmin MapSource files. + + Copyright (C) 2002 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + */ + +#include +#include + +#include "defs.h" +#include + +static FILE *mapsource_file_in; +static FILE *mapsource_file_out; + +static void +mapsource_rd_init(const char *fname) +{ + mapsource_file_in = fopen(fname, "r"); + if (mapsource_file_in == NULL) { + fprintf(stderr, "Cannot open '%s' for reading\n", fname); + exit(1); + } +} + +static void +mapsource_rd_deinit(void) +{ + fclose(mapsource_file_in); +} + +static void +mapsource_wr_init(const char *fname) +{ + mapsource_file_out = fopen(fname, "w"); + if (mapsource_file_out == NULL) { + fprintf(stderr, "Cannot open '%s' for writing\n", fname); + exit(1); + } +} + +static void +mapsource_wr_deinit(void) +{ + fclose(mapsource_file_out); +} + +static void +mapsource_read(void) +{ + char name[9], date[20], timeb[20]; + char ibuf[200]; + double lat,lon; + char latdir, londir; + int latd, lond; + float latf, lonf; + int alt; + char altunits[10]; + char icon[20]; + waypoint *wpt_tmp; + + while (fgets(ibuf, sizeof(ibuf), mapsource_file_in)) { + sscanf(ibuf, + "Waypoint %s %s %s %c%d %f %c%d %f %d %s Symbol & Name %s", + name, date, timeb, &latdir, &latd, &latf, &londir, &lond, &lonf, &alt, altunits, icon); + wpt_tmp = calloc(sizeof(*wpt_tmp),1); + if (wpt_tmp == NULL) { + fatal("MAPSOURCE: cannot allocate memory\n"); + } +/* FIXME: Implement actual appropriate conversion */ + wpt_tmp->position.altitude.altitude_meters = alt * 3.0; + wpt_tmp->shortname = strdup(name); + wpt_tmp->description = strdup(name); + + lat = latd + latf/100.0; + lon = lond + lonf/100.0; + if (latdir == 'S') lat = -lat; + if (londir == 'W') lon = -lon; + wpt_tmp->position.latitude.degrees = lat; + wpt_tmp->position.longitude.degrees = lon; + + waypt_add(wpt_tmp); + } +} + +static void +mapsource_waypt_pr(waypoint *waypointp) +{ + char tbuf[1024]; + char *tp = tbuf; + int d; + strftime(tbuf, sizeof(tbuf), "%d-%b-%y %I:%M:%S%p", localtime(&waypointp->creation_time)); + while (*tp) { + *tp = toupper(*tp); + tp++; + } +/* FIXME: cure the sign dependencies here. */ + fprintf(mapsource_file_out, "Waypoint %s %s ", waypointp->shortname, tbuf); + fprintf(mapsource_file_out, "N%02.0f", waypointp->position.latitude.degrees); + d = waypointp->position.latitude.degrees; + fprintf(mapsource_file_out, " %06.3f ", (waypointp->position.latitude.degrees - d) * 100); + fprintf(mapsource_file_out, "W%02.0f", fabs(waypointp->position.longitude.degrees)); + d = fabs(waypointp->position.longitude.degrees); + fprintf(mapsource_file_out, " %06.3f ", (fabs(waypointp->position.longitude.degrees) - d) * 100); + fprintf(mapsource_file_out, "0 ft Symbol & Name Unknown\n"); +} + +void +mapsource_write(void) +{ + waypt_disp_all(mapsource_waypt_pr); + +} + +ff_vecs_t mapsource_vecs = { + mapsource_rd_init, + mapsource_wr_init, + mapsource_rd_deinit, + mapsource_wr_deinit, + mapsource_read, + mapsource_write, +}; diff --git a/gpsman/pcx.c b/gpsman/pcx.c new file mode 100644 index 000000000..f65b83ed2 --- /dev/null +++ b/gpsman/pcx.c @@ -0,0 +1,155 @@ +/* + Access to Garmin PCX5 files. + + Copyright (C) 2002 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA +*/ + + +#include "defs.h" +#include + +static FILE *file_in; +static FILE *file_out; + +static void +rd_init(const char *fname) +{ + file_in = fopen(fname, "r"); + if (file_in == NULL) { + fatal("GPSUTIL: Cannot open %s for reading\n", fname); + } +} + +static void +rd_deinit(void) +{ + fclose(file_in); +} + +static void +wr_init(const char *fname) +{ + file_out = fopen(fname, "w"); + if (file_out == NULL) { + fatal("GPSUTIL: Cannot open %s for writing\n", fname); + } +} + +static void +wr_deinit(void) +{ + fclose(file_out); +} + +static void +data_read(void) +{ + char name[9], desc[90]; + double lat,lon; + char latdir, londir; + long alt; + char alttype; + char icon[3] = {0}; + char date[10]; + char time[9]; + waypoint *wpt_tmp; + char ibuf[100]; + + for(;fgets(ibuf, sizeof(ibuf), file_in);) { + switch (ibuf[0]) { + case 'W': + sscanf(ibuf, "W %s %c%lf %c%lf %s %s %ld %90[^\n']", + name, &latdir, &lat, &londir, &lon, + date, time, &alt, desc); + wpt_tmp = calloc(sizeof(*wpt_tmp), 1); + wpt_tmp->position.altitude.altitude_meters = alt; + wpt_tmp->shortname = strdup(name); + wpt_tmp->description = strdup(desc); + + if (latdir == 'S') lat = -lat; + if (londir == 'W') lon = -lon; + wpt_tmp->position.longitude.degrees = lon/100.0; + wpt_tmp->position.latitude.degrees = lat/100.0; + wpt_tmp->icon_descr = strdup(icon); + waypt_add(wpt_tmp); + } + } +} + +static void +gpsutil_disp(waypoint *wpt) +{ + double lon,lat; + signed int ilon, ilat; + const char *icon_token = "0"; + char tbuf[1024]; + char *tp = tbuf; + time_t tm = wpt->creation_time; + + ilon = (signed int)wpt->position.longitude.degrees; + ilat = (signed int)wpt->position.latitude.degrees; + lon = (ilon * 100.0) + (wpt->position.longitude.degrees - ilon) * 60.0; + lat = (ilat * 100.0) + (wpt->position.latitude.degrees - ilat) * 60.0; + + if (tm == 0) + tm = time(NULL); + strftime(tbuf, sizeof(tbuf), "%d-%b-%y %I:%M:%S", localtime(&tm)); + while (*tp) { + *tp = toupper(*tp); + tp++; + } + + fprintf(file_out, "W %-6.6s %c%08.5f %c%011.5f %s %5d %-40.40s %5e %s\n", + wpt->shortname, + lat < 0.0 ? 'S' : 'N', + fabs(lat), + lon < 0.0 ? 'W' : 'E', + fabs(lon), + tbuf, + -9999, + wpt->description, + 0.0, + icon_token); +} + +static void +data_write(void) +{ +fprintf(file_out, +"H SOFTWARE NAME & VERSION\n" +"I PCX5 2.09\n" +"\n" +"H R DATUM IDX DA DF DX DY DZ\n" +"M G WGS 84 121 +0.000000e+00 +0.000000e+00 +0.000000e+00 +0.000000e+00 +0.000000e+00\n" +"\n" +"H COORDINATE SYSTEM\n" +"U LAT LON DM\n" +"\n" +"H IDNT LATITUDE LONGITUDE DATE TIME ALT DESCRIPTION PROXIMITY SYMBOL ;waypts\n"); + + waypt_disp_all(gpsutil_disp); +} + + +ff_vecs_t pcx_vecs = { + rd_init, + wr_init, + rd_deinit, + wr_deinit, + data_read, + data_write, +}; diff --git a/gpsman/queue.c b/gpsman/queue.c new file mode 100644 index 000000000..1cb6e6efb --- /dev/null +++ b/gpsman/queue.c @@ -0,0 +1,42 @@ +/* + Generic queue utilities. + + Copyright (C) 2002 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include "queue.h" + +void +enqueue(queue *new, queue *old) +{ + new->next = old->next; + new->prev = old; + old->next->prev = new; + old->next = new; +} + +queue * +dequeue(queue *element) +{ + queue *prev = element->prev; + queue *next = element->next; + + next->prev = prev; + prev->next = next; + return element; +} diff --git a/gpsman/queue.h b/gpsman/queue.h new file mode 100644 index 000000000..84bce2a56 --- /dev/null +++ b/gpsman/queue.h @@ -0,0 +1,43 @@ +/* + Generic queueing utilities. + + Copyright (C) 2002 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +typedef struct queue { + struct queue *next; + struct queue *prev; +} queue; + +void enqueue(queue *new, queue *old); +queue * dequeue(queue *element); + +#define QUEUE_INIT(head) (head)->next = (head)->prev = head +#define QUEUE_FIRST(head) (head)->next +#define QUEUE_NEXT(element) (element)->next +#define QUEUE_LAST(head) (head)->prev +#define QUEUE_EMPTY (head)->next = head + +#define ENQUEUE_TAIL(listhead, element) \ + enqueue(element, (listhead)->prev) + +#define QUEUE_FOR_EACH(listhead, element, tmp) \ + for ((element) = QUEUE_FIRST(listhead); \ + (tmp) = QUEUE_NEXT(element), \ + (element) != (listhead); \ + (element) = (tmp)) diff --git a/gpsman/reference/gl.loc b/gpsman/reference/gl.loc new file mode 100644 index 000000000..518337cca --- /dev/null +++ b/gpsman/reference/gl.loc @@ -0,0 +1,47 @@ + + + + +http://www.geocaching.com/seek/cache_details.asp?ID=3771 + + + + +http://www.geocaching.com/seek/cache_details.asp?ID=6711 + + + + +http://www.geocaching.com/seek/cache_details.asp?ID=7211 + + + + +D=9641 + + + + +http://www.geocaching.com/seek/cache_details.asp?ID=10019 + + + + +http://www.geocaching.com/seek/cache_details.asp?ID=11121 + + + + +http://www.geocaching.com/seek/cache_details.asp?ID=12447 + + + + +http://www.geocaching.com/seek/cache_details.asp?ID=12666 + + + + +http://www.geocaching.com/seek/cache_details.asp?ID=12669 + + diff --git a/gpsman/reference/gu.wpt b/gpsman/reference/gu.wpt new file mode 100644 index 000000000..e23f70209 --- /dev/null +++ b/gpsman/reference/gu.wpt @@ -0,0 +1,9 @@ +GCEBB 3597.203N 08713.470W 0000000m Mountain Bike Heaven by susy13 a +GC1A37 3609.068N 08667.955W 0000000m The Troll by a182pilot & Famil a +GC1C2B 3599.627N 08662.012W 0000000m Dive Bomber by JoGPS & family a +GC25A9 3603.848N 08664.862W 0000000m FOSTER by JoGPS & Family a +GC2723 3611.218N 08674.177W 0000000m Logan Lighthouse by JoGps & Fa a +GC2B71 3606.408N 08679.052W 0000000m Ganier Cache by Susy1313 a +GC309F 3608.777N 08680.973W 0000000m Shy's Hill by FireFighterEng33 a +GC317A 3605.750N 08689.200W 0000000m GittyUp by JoGPS / Warner Park a +GC317D 3608.280N 08686.728W 0000000m Inlighting by JoGPS / Warner P a diff --git a/gpsman/route.c b/gpsman/route.c new file mode 100644 index 000000000..8365348cb --- /dev/null +++ b/gpsman/route.c @@ -0,0 +1,47 @@ +/* + Copyright (C) 2002 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include +#include "defs.h" + +static queue route_head; + +void +route_init(void) +{ + QUEUE_INIT(&route_head); +} + +void +route_add(waypoint *wpt) +{ + ENQUEUE_TAIL(&route_head, &wpt->Q); +} + +void +route_disp_all(waypt_cb cb) +{ + queue *elem, *tmp; + waypoint *waypointp; + + QUEUE_FOR_EACH(&route_head, elem, tmp) { + waypointp = (waypoint *) elem; + (*cb)(waypointp); + } +} diff --git a/gpsman/testo b/gpsman/testo new file mode 100755 index 000000000..17f80eebc --- /dev/null +++ b/gpsman/testo @@ -0,0 +1,45 @@ +PNAME=./gpsbabel + +# Geocaching .loc +${PNAME} -i geo -f geocaching.loc -o geo -F /tmp/gl.loc +diff /tmp/gl.loc reference + +# GPSUtil +${PNAME} -i geo -f geocaching.loc -o gpsutil -F /tmp/gu.wpt +diff /tmp/gu.wpt reference + +# GPSman +${PNAME} -i geo -f geocaching.loc -o gpsman -F /tmp/gm.gm +${PNAME} -i gpsman -f /tmp/gm.gm -o gpsutil -F /tmp/gm.gm+ +diff /tmp/gm.gm+ /tmp/gu.wpt + +# GPX +${PNAME} -i geo -f geocaching.loc -o gpx -F /tmp/gl.gpx +${PNAME} -i gpx -f /tmp/gl.gpx -o gpsutil -F /tmp/gpx.gpx +diff /tmp/gpx.gpx /tmp/gu.wpt + +# Magellan Mapsend +${PNAME} -i geo -f geocaching.loc -o mapsend -F /tmp/mm.mapsend +${PNAME} -i mapsend -f /tmp/mm.mapsend -o gpsutil -F /tmp/mm.gps +diff /tmp/mm.gps /tmp/gu.wpt + +# Garmin Mapsource +#${PNAME} -i geo -f geocaching.loc -o mapsource -F /tmp/mm.mapsource +#${PNAME} -i mapsource -f /tmp/mm.mapsource -o gpsutil -F /tmp/ms.gps +# diff /tmp/ms.gps /tmp/gu.wpt + +# Magellan serial +# TODO + + +# CSV (Comma separated value) data. + +#${PNAME} -i geo -f geocaching.loc -o csv -F /tmp/csv.csv +#${PNAME} -i csv -f /tmp/csv.csv -o gpsutil -F /tmp/csv2.csv +#diff /tmp/csv2.csv /tmp/gu.wpt + +# PCX (Garmin mapsource import) file format +${PNAME} -i geo -f geocaching.loc -o pcx -F /tmp/mm.pcx +${PNAME} -i pcx -f /tmp/mm.pcx -o gpsutil -F /tmp/pcx.gps +diff /tmp/mm.gps /tmp/gu.wpt + diff --git a/gpsman/tiger.c b/gpsman/tiger.c new file mode 100644 index 000000000..da611fc26 --- /dev/null +++ b/gpsman/tiger.c @@ -0,0 +1,117 @@ +/* + Access to U.S. Census Bureau "tiger" format. + + Copyright (C) 2002 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include "defs.h" +#include "magellan.h" + +static FILE *file_in; +static FILE *file_out; + +static void +rd_init(const char *fname) +{ + file_in = fopen(fname, "r"); + if (file_in == NULL) { + fatal("GPSUTIL: Cannot open %s for reading\n", fname); + } +} + +static void +rd_deinit(void) +{ + fclose(file_in); +} + +static void +wr_init(const char *fname) +{ + file_out = fopen(fname, "w"); + if (file_out == NULL) { + fatal("GPSUTIL: Cannot open %s for writing\n", fname); + } +} + +static void +wr_deinit(void) +{ + fclose(file_out); +} + +static void +data_read(void) +{ +abort(); +#if 0 + char name[9], desc[30]; + double lat,lon; + char latdir, londir; + long alt; + char alttype; + char icon[3] = {0}; + waypoint *wpt_tmp; + + while( fscanf(file_in, "%s %le%c %le%c %ld%c %30[^,] %c", + name, &lat, &latdir, &lon, &londir, + &alt, &alttype, desc, icon) > 0) { + wpt_tmp = calloc(sizeof(*wpt_tmp),1); + if (wpt_tmp == NULL) { + fatal("GPSMAN: cannot allocate memory\n"); + } + wpt_tmp->position.altitude.altitude_meters = alt; + wpt_tmp->shortname = strdup(name); + wpt_tmp->description = strdup(desc); + wpt_tmp->creation_time = time(NULL); + + if (latdir == 'S') lat = -lat; + if (londir == 'W') lon = -lon; + wpt_tmp->position.longitude.degrees = lon/100.0; + wpt_tmp->position.latitude.degrees = lat/100.0; + wpt_tmp->icon_descr = strdup(icon); + + waypt_add(wpt_tmp); + } +#endif +} + +static void +gpsutil_disp(waypoint *wpt) +{ + fprintf(file_out, "%f,%f:redpin:%s\n", + wpt->position.longitude.degrees, + wpt->position.latitude.degrees, + wpt->description); +} + +static void +data_write(void) +{ + waypt_disp_all(gpsutil_disp); +} + + +ff_vecs_t tiger_vecs = { + rd_init, + wr_init, + rd_deinit, + wr_deinit, + data_read, + data_write, +}; diff --git a/gpsman/util.c b/gpsman/util.c new file mode 100644 index 000000000..4433b4678 --- /dev/null +++ b/gpsman/util.c @@ -0,0 +1,64 @@ +/* + Misc utilities. + + Copyright (C) 2002 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include "defs.h" +#include +#include + +coord +mkposn(const char *string) +{ + coord coord = {0}; + sscanf(string, "%lf", &coord.degrees); + return coord; +} + +void +printposn(coord *c, int is_lat) +{ + char d; + if (is_lat) { + if (c->degrees < 0) d = 'S'; else d = 'N'; + } else { + if (c->degrees < 0) d = 'W'; else d = 'E'; + } + printf("%lf%c ", fabs(c->degrees), d); +} + +void +fprintdms(FILE *file, coord *c, int is_lat) +{ + char d; + if (is_lat) { + if (c->degrees < 0) d = 'S'; else d = 'N'; + } else { + if (c->degrees < 0) d = 'W'; else d = 'E'; + } + fprintf(file, "%c%lf\t", d, fabs(c->degrees)); +} +void +fatal(const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + exit(1); +} diff --git a/gpsman/vecs.c b/gpsman/vecs.c new file mode 100644 index 000000000..09dbe1d16 --- /dev/null +++ b/gpsman/vecs.c @@ -0,0 +1,122 @@ +/* + Describe vectors containing file operations. + + Copyright (C) 2002 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include +#include "defs.h" + +typedef struct { + ff_vecs_t *vec; + char *name; + char *desc; +} vecs_t; + +extern ff_vecs_t geo_vecs; +extern ff_vecs_t gpsman_vecs; +extern ff_vecs_t gpx_vecs; +extern ff_vecs_t mag_vecs; +extern ff_vecs_t mapsend_vecs; +extern ff_vecs_t mapsource_vecs; +extern ff_vecs_t gpsutil_vecs; +extern ff_vecs_t tiger_vecs; +extern ff_vecs_t pcx_vecs; +extern ff_vecs_t csv_vecs; + +static +vecs_t vec_list[] = { + { + &geo_vecs, + "geo", + "Geocaching.com .loc" + }, + { + &gpsman_vecs, + "gpsman", + "GPSman" + }, + { + &gpx_vecs, + "gpx", + "GPX XML" + }, + { + &mag_vecs, + "magellan", + "Magellan protocol" + }, + { + &mapsend_vecs, + "mapsend", + "Magellan Mapsend" + }, + { + &pcx_vecs, + "pcx", + "Garmin PCX5" + }, + { + &mapsource_vecs, + "mapsource", + "Garmin Mapsource" + }, + { + &gpsutil_vecs, + "gpsutil", + "gpsutil" + }, + { + &tiger_vecs, + "tiger", + "U.S. Census Bureau Tiger Mapping Service" + }, + { + &csv_vecs, + "csv", + "Comma separated values" + }, + { + NULL, + NULL, + NULL + } +}; + +ff_vecs_t * +find_vec(char *const vecname) +{ + vecs_t *vec = vec_list; + while (vec->vec) { + if (strcmp(vecname, vec->name) == 0) { + return vec->vec; + } + vec++; + } + return NULL; +} + +void +disp_vecs(void) +{ + vecs_t *vec; + for (vec = vec_list; vec->vec; vec++) { + printf("%-20.20s %-50.50s\n", + vec->name, vec->desc); + } +} diff --git a/gpsman/waypt.c b/gpsman/waypt.c new file mode 100644 index 000000000..20bb03bc3 --- /dev/null +++ b/gpsman/waypt.c @@ -0,0 +1,71 @@ +/* + Perform various operations on waypoints. + + Copyright (C) 2002 Robert Lipe, robertlipe@usa.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + + */ + +#include +#include "defs.h" + +static queue waypt_head; +static unsigned int waypt_ct; + +void +waypt_init(void) +{ + QUEUE_INIT(&waypt_head); +} + +void +waypt_add(waypoint *wpt) +{ + ENQUEUE_TAIL(&waypt_head, &wpt->Q); + waypt_ct++; +} + +unsigned int +waypt_count(void) +{ + return waypt_ct; +} + +void +waypt_disp(waypoint *wpt) +{ + if (wpt->creation_time) { + printf("%s ", ctime(&wpt->creation_time)); + } + printposn(&wpt->position.latitude,1); + printposn(&wpt->position.longitude,0); + printf("%s/%s %f\n", + wpt->shortname, + wpt->description, + wpt->position.altitude.altitude_meters); +} + +void +waypt_disp_all(waypt_cb cb) +{ + queue *elem, *tmp; + waypoint *waypointp; + + QUEUE_FOR_EACH(&waypt_head, elem, tmp) { + waypointp = (waypoint *) elem; + (*cb) (waypointp); + } +} -- 2.30.2